package org.springblade.modules.repair.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.HttpPost;
import org.codehaus.jettison.Convention;
import org.slf4j.Logger;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.modules.repair.vo.weixin.WxUserInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author zcc
 * @version 1.0
 * @date 2021/5/26 11:39
 */
@Slf4j
@Component
public class WeiXinUtil {
	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	private final static String WEI_XIN_TOKEN = "WEI_XIN_TOKEN";

	private final static String WEI_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

	private final static String WEI_XIN_ACCESS_TOKEN = "WEI_XIN_ACCESS_TOKEN";

	private final static String WEI_ACCESS_TOKEN_URL = " https://api.weixin.qq.com/cgi-bin/token";

	private final static String WEI_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";

	private final static String WEI_SEND_TEMPLATE = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";

	private final static String WEI_USER_INFO = "https://api.weixin.qq.com/cgi-bin/user/info";


	@Value("${weixin.appId}")
	private String appId;

	@Value("${weixin.appSecret}")
	private String appSecret;


	/**
	 * 获取微信token
	 *
	 * @param code code编码
	 * @return token
	 */
	private String getWeiXinToken(String code) {
		Map<String, Object> params = new HashMap<>(10);
		params.put("appid", appId);
		params.put("secret", appSecret);
		params.put("code", code);
		params.put("grant_type", "authorization_code");
		String resultBody = HttpUtil.get(WEI_TOKEN_URL, params);
		log.info("<---------------------------- {WECHAT_TOKEN:}"+resultBody+"------------------------------->");
		Map map = JSON.parseObject(resultBody, Map.class);
		return Convert.toStr(map.get("access_token"));
	}

	/**
	 * 获取access_token
	 * @return
	 */
	public String getAccessToken() {
		String accessToken = (String) redisTemplate.opsForValue().get(WEI_XIN_ACCESS_TOKEN);
		if (StrUtil.isEmpty(accessToken)) {
			Map<String, Object> params = new HashMap<>(4);
			params.put("appid", appId);
			params.put("secret", appSecret);
			params.put("grant_type", "client_credential");
			String resultBody = HttpUtil.get(WEI_ACCESS_TOKEN_URL, params);
			log.info("<---------------------------- {WECHAT_ACCESS_TOKEN:}"+resultBody+"------------------------------->");
			Map resultMap = JSON.parseObject(resultBody, Map.class);
			accessToken = Convert.toStr(resultMap.get("access_token"));
			redisTemplate.opsForValue().set(WEI_XIN_ACCESS_TOKEN, accessToken, Convert.toLong(resultMap.get("expires_in")), TimeUnit.SECONDS);
		}
		return accessToken;
	}

	/**
	 * 获取微信用户授权信息
	 *
	 * @param code 授权信息
	 * @return 结果集，头像，名称openid
	 */
	public String getWeiUserInfo(String code) {
		String weiXinToken = getWeiXinToken(code);
		Map<String, Object> params = new HashMap<>(10);
		params.put("access_token", weiXinToken);
		params.put("openid", "OPENID");
		params.put("lang", "zh_CN");
		return HttpUtil.get(WEI_USER_INFO_URL, params);
	}

	/**
	 * 获取用户信息
	 * @param openid
	 * @param accessToken
	 * @return
	 */
	public WxUserInfo getUserInfo(String openid, String accessToken) {
		Map<String, Object> params = new HashMap<>(4);
		params.put("access_token", accessToken);
		params.put("openid", openid);
		params.put("lang", "zh_CN");
		String resultBody = HttpUtil.get(WEI_USER_INFO, params);
		log.info("<---------------------------- {USER_INFO:}"+resultBody+"------------------------------->");
		WxUserInfo userInfo = JSONUtil.toBean(resultBody, WxUserInfo.class);
		return userInfo;
	}

	/**
	 * 发送公众号模板消息
	 *
	 * @param body
	 * @return
	 */
	public String sendTemplateMessage(String body) {

		String accessToken = (String) redisTemplate.opsForValue().get(WEI_XIN_ACCESS_TOKEN);
		if (StrUtil.isEmpty(accessToken)) {
			Map<String, Object> map = new HashMap<>(16);
			map.put("grant_type", "client_credential");
			map.put("appid", appId);
			map.put("secret", appSecret);
			String s = HttpUtil.get(WEI_ACCESS_TOKEN_URL, map);
			Map resultMap = JSON.parseObject(s, Map.class);
			accessToken = Convert.toStr(resultMap.get("access_token"));
			redisTemplate.opsForValue().set(WEI_XIN_ACCESS_TOKEN, accessToken, Convert.toLong(resultMap.get("expires_in")), TimeUnit.SECONDS);
		}
		return HttpUtil.createPost(WEI_SEND_TEMPLATE + accessToken).body(body).execute().body();
	}
}
